package com.loveprogrammer.metadata.asynctool.wrapper;

import com.loveprogrammer.metadata.asynctool.callback.DefaultCallback;
import com.loveprogrammer.metadata.asynctool.callback.ICallback;
import com.loveprogrammer.metadata.asynctool.callback.IWorker;
import com.loveprogrammer.metadata.asynctool.worker.DependWrapper;
import com.loveprogrammer.metadata.asynctool.worker.WorkResult;

import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @ClassName WorkerWrapper
 * @Description 任务封装
 * @Author admin
 * @Date 2023/11/13 13:47
 * @Version 1.0
 */
public class WorkerWrapper<T,V> {

    private String  id;

    private T param;

    private IWorker<T,V> worker;

    private ICallback<T,V> callback;

    private List<WorkerWrapper<?,?>> nextWrappers;

    private List<DependWrapper> dependWrappers;

    /**
     * 标记该事件是否已经被处理过了，譬如已经超时返回false了，后续rpc又收到返回值了，则不再二次回调
     * 经试验,volatile并不能保证"同一毫秒"内,多线程对该值的修改和拉取
     * 1-finish, 2-error, 3-working
     */
    private AtomicInteger state = new AtomicInteger(0);

    /**
     * 该map存放所有wrapper的id和wrapper映射
     */
    private Map<String,WorkerWrapper> forParamUseWrappers;

    /**
     * 是否在执行自己前，去校验nextWrapper的执行结果<p>
     * 1   4
     * -------3
     * 2
     * 如这种在4执行前，可能3已经执行完毕了（被2执行完后触发的），那么4就没必要执行了。
     * 注意，该属性仅在nextWrapper数量<=1时有效，>1时的情况是不存在的
     */
    private volatile boolean needCheckNextWrapperResult = true;

    /**
     * 钩子变量，用来存放临时的结果
     */
    private volatile WorkResult<V> workResult = WorkResult.defaultResult();

    private static final int FINISH = 1;
    private static final int ERROR = 2;
    private static final int WORKING = 3;
    private static final int INIT = 0;

    private WorkerWrapper(String id, T param, IWorker<T, V> worker, ICallback<T, V> callback) {
        if (worker == null) {
            throw new NullPointerException("async.worker is null");
        }
        this.id = id;
        this.param = param;
        this.worker = worker;
        //允许不设置回调
        if (callback == null) {
            callback = new DefaultCallback<>();
        }
        this.callback = callback;
    }



    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public T getParam() {
        return param;
    }

    public void setParam(T param) {
        this.param = param;
    }

    public IWorker<T, V> getWorker() {
        return worker;
    }

    public void setWorker(IWorker<T, V> worker) {
        this.worker = worker;
    }

    public ICallback<T, V> getCallback() {
        return callback;
    }

    public void setCallback(ICallback<T, V> callback) {
        this.callback = callback;
    }

    public List<WorkerWrapper<?, ?>> getNextWrappers() {
        return nextWrappers;
    }

    public void setNextWrappers(List<WorkerWrapper<?, ?>> nextWrappers) {
        this.nextWrappers = nextWrappers;
    }

    public List<DependWrapper> getDependWrappers() {
        return dependWrappers;
    }

    public void setDependWrappers(List<DependWrapper> dependWrappers) {
        this.dependWrappers = dependWrappers;
    }
}
